/** * Copyright (c) 2009--2012 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.redhat.rhn.internal.doclet; import com.sun.javadoc.ClassDoc; import com.sun.javadoc.MethodDoc; import com.sun.javadoc.RootDoc; import com.sun.javadoc.Tag; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * * TestDoclet * @version $Rev$ */ public class ApiDoclet { private static final String XMLRPC_DOC = "@xmlrpc.doc"; private static final String XMLRPC_PARAM = "@xmlrpc.param"; private static final String XMLRPC_RETURN = "@xmlrpc.returntype"; private static final String XMLRPC_NAMESPACE = "@xmlrpc.namespace"; private static final String XMLRPC_IGNORE = "@xmlrpc.ignore"; private static final String DEPRECATED = "@deprecated"; private static final String SINCE = "@since"; public static final String API_MACROS_FILE = "macros.txt"; public static final String API_HANDLER_FILE = "handler.txt"; public static final String API_INDEX_FILE = "apiindex.txt"; public static final String API_FOOTER_FILE = "api_index_ftr.txt"; public static final String API_HEADER_FILE = "api_index_hdr.txt"; protected ApiDoclet() { } /** * start the doclet * @param root the document root * @param docType 'jsp' or 'wiki' * @return boolean * @throws Exception e */ public static boolean start(RootDoc root, String docType) throws Exception { ClassDoc[] classes = root.classes(); List<ClassDoc> serializers = getSerializers(classes); List<ClassDoc> handlers = getHandlers(classes); Map<String, String> serialMap = getSerialMap(serializers); List<Handler> handlerList = new ArrayList<Handler>(); for (ClassDoc clas : handlers) { Handler handler = new Handler(); if (clas.tags(XMLRPC_IGNORE).length > 0) { continue; } Tag name = getFirst(clas.tags(XMLRPC_NAMESPACE)); if (name != null) { handler.setName(name.text()); } else { String error = "Someone didn't set " + XMLRPC_NAMESPACE + " correctly on " + clas.name(); error += " If you really did not want this handler to appear in " + "the API docs. Add @xmlrpc.ignore to the class javadoc. "; throw new Exception(error); } handler.setClassName(clas.name()); Tag classDesc = getFirst(clas.tags(XMLRPC_DOC)); if (classDesc != null) { handler.setDesc(classDesc.text()); } for (MethodDoc method : clas.methods()) { if (method.isPublic() && getFirst(method.tags(XMLRPC_IGNORE)) == null) { ApiCall call = new ApiCall(method); call.setName(method.name()); Tag methodDoc = getFirst(method.tags(XMLRPC_DOC)); if (methodDoc != null) { if (docType.equals("docbook")) { call.setDoc(DocBookWriter.transcode(methodDoc.text())); } else { call.setDoc(methodDoc.text()); } } for (Tag param : method.tags(XMLRPC_PARAM)) { if (docType.equals("docbook")) { call.addParam(DocBookWriter.transcode(param.text())); } else { call.addParam(param.text()); } } if (method.tags(DEPRECATED).length > 0) { call.setDeprecated(true); call.setDeprecatedReason(getFirst( method.tags(DEPRECATED)).text()); } if (method.tags(SINCE).length > 0) { call.setSinceAvailable(true); call.setSinceVersion(getFirst( method.tags(SINCE)).text()); } Tag tag = getFirst(method.tags(XMLRPC_RETURN)); if (tag != null) { //run templating on the return value //call.setReturnDoc(serialHelper.renderTemplate(tag.text())); call.setReturnDoc(tag.text()); } //Finally add the newly built api to the handler handler.addApiCall(call); } } //Then simply sort the apicalls and add the handler to our List Collections.sort(handler.getCalls()); handlerList.add(handler); } Collections.sort(handlerList); DocWriter writer; if (docType.equals("jsp")) { writer = new JSPWriter(); } else if (docType.equals("html")) { writer = new HtmlWriter(); } else if (docType.equals("list")) { writer = new ListWriter(); } else if (docType.equals("singlepage")) { writer = new SinglePageWriter(); } else if (docType.equals("docbook")) { writer = new DocBookWriter(); } else { writer = new JSPWriter(); } writer.write(handlerList, serialMap); return true; } private static List<ClassDoc> getSerializers(ClassDoc[] classes) { List<ClassDoc> serializers = new ArrayList<ClassDoc>(); for (ClassDoc clas : classes) { ClassDoc baseSerializerIface = clas.findClass( "redstone.xmlrpc.XmlRpcCustomSerializer"); if (clas.subclassOf(baseSerializerIface)) { serializers.add(clas); } } return serializers; } private static Map<String, String> getSerialMap(List<ClassDoc> classes) { Map<String, String> map = new HashMap<String, String>(); for (ClassDoc clas : classes) { Tag tag = getFirst(clas.tags(XMLRPC_DOC)); if (tag != null) { map.put(clas.name(), tag.text()); } } return map; } private static List<ClassDoc> getHandlers(ClassDoc[] classes) { List<ClassDoc> handlers = new ArrayList<ClassDoc>(); for (ClassDoc clas : classes) { if (clas.superclass() != null) { if (clas.superclass().name().equals("BaseHandler")) { handlers.add(clas); } } } Collections.sort(handlers); return handlers; } private static Tag getFirst(Tag[] tags) { if (tags.length > 0) { return tags[0]; } return null; } }